from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.urls import reverse
from django.apps import apps

from users.models import User


def get_initial_group():

    """ Получаем начальную подкатегорию """

    model = apps.get_model(app_label='content', model_name='group')
    return model.objects.get(name='начальная').pk


class Tag(models.Model):

    """ Тег для метки какого то материала """

    title = models.CharField(max_length=250)
    description = models.TextField()
    created = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created']

    def __str__(self):
        return self.title


class Group(models.Model):

    """ Группа """

    name = models.CharField(max_length=50, verbose_name='Группа')
    slug = models.SlugField(verbose_name='URL')
    created = models.DateTimeField(auto_now_add=True)
    content = models.CharField(max_length=300, verbose_name='Тип контента')

    class Meta:
        verbose_name = 'Группа'
        verbose_name_plural = 'Группа'
        ordering = ['-created']

    def get_absolute_url(self):
        return reverse('content:showing_object_category',
                       kwargs={'content_type': self.content, 'object': self.slug})

    def get_update_url(self):
        return reverse('content:updating_object',
                       kwargs={'content_type': 'group', 'object': self.slug})

    def get_delete_url(self):
        return reverse('content:deleting_object',
                       kwargs={'main_object': 'group',
                               'content_type': self.content,
                               'object': self.slug})

    def __str__(self):
        return self.name


class Content(models.Model):

    """ Контент, который может быть добавлен пользователем (картинки, видео слова и т.д.) """

    tags = models.ManyToManyField(Tag, related_name='%(class)s_related', blank=True)
    created = models.DateTimeField(auto_now_add=True, verbose_name='Создано')
    updated = models.DateTimeField(auto_now=True, verbose_name='Обновлено')
    title = models.CharField(max_length=250, unique=True)
    description = models.TextField(blank=True)
    slug = models.SlugField(verbose_name='URL')
    group = models.ForeignKey(Group, on_delete=models.CASCADE, null=True, blank=True)

    class Meta:
        abstract = True
        ordering = ['-created']
        verbose_name = 'Содержимое'
        verbose_name_plural = 'Содержимое'

    def get_related_notes(self):

        """ Получаем связанные заметики """

        return self.additionally.all()

    def get_content_type(self):

        """ Получаем тип содержимого """

        return type(self).__name__.lower()


    def get_add_group_url(self):
        return reverse('content:add_some_group',
                       kwargs={'content_type': self.slug})

    def get_add_url(self):

        """ Получаем url для добавления объекта какого-то типа """

        return reverse('content:showing_content',
                       kwargs={'content_type': self.slug})


    def __str__(self):
        return self.title


class Video(Content):

    """ Видео пользователя """

    url = models.URLField(verbose_name='Видео')

    class Meta:
        verbose_name = 'Видео'
        verbose_name_plural = 'Видео'


class Image(Content):

    """ Изображение пользователя """

    photo = models.ImageField(upload_to="%Y/%m/%d/")

    class Meta:
        verbose_name = 'Изображение'
        verbose_name_plural = 'Изображения'

    def get_absolute_url(self):
        return reverse('content:showing_object_detail',
                       kwargs={'content_type': 'image',
                               'object': self.slug})

    def get_update_url(self):
        return reverse('content:updating_object',
                       kwargs={'content_type': 'image',
                               'object': self.slug})

    def get_delete_url(self):

        """ Получаем url для удаления объекта """

        if self.group:
            return reverse('content:deleting_object', kwargs={'main_object': 'image',
                                                              'content_type': self.group.slug,
                                                              'object': self.slug})
        else:
            return reverse('content:deleting_object', kwargs={'main_object': 'image',
                                                              'content_type': 'not_group',
                                                              'object': self.slug})


class Article(Content):

    """ Какие-то статьи написанные пользователем """

    class Meta:
        verbose_name = 'Статья'
        verbose_name_plural = 'Статьи'
        ordering = ['-created']

    def get_absolute_url(self):
        return reverse('content:showing_object_detail',
                       kwargs={'content_type': 'article',
                               'object': self.slug})

    def get_update_url(self):
        return reverse('content:updating_object',
                       kwargs={'content_type': 'article',
                               'object': self.slug})

    def get_delete_url(self):

        """ Получаем url для удаления объекта """

        if self.group:
            return reverse('content:deleting_object', kwargs={'main_object': 'article',
                                                              'content_type': self.group.slug,
                                                              'object': self.slug})
        else:
            return reverse('content:deleting_object', kwargs={'main_object': 'article',
                                                              'content_type': 'not_group',
                                                              'object': self.slug})


class Rule(Content):

    """ Какое-то правило добаленное пользователем """

    class Meta:
        verbose_name = 'Правило'
        verbose_name_plural = 'Правила'
        ordering = ['-created']

    def get_absolute_url(self):
        return reverse('content:showing_object_detail',
                       kwargs={'content_type': 'rule',
                               'object': self.slug})

    def get_update_url(self):
        return reverse('content:updating_object',
                       kwargs={'content_type': 'rule',
                               'object': self.slug})

    def get_delete_url(self):

        """ Получаем url для удаления объекта """

        if self.group:
            return reverse('content:deleting_object', kwargs={'main_object': 'rule',
                                                              'content_type': self.group.slug,
                                                              'object': self.slug})
        else:
            return reverse('content:deleting_object', kwargs={'main_object': 'rule',
                                                              'content_type': 'not_group',
                                                              'object': self.slug})


class Additionaly(models.Model):

    """ Дополнительная информация о содержимом """

    note = models.TextField(verbose_name='Заметка')
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    photo = models.ImageField(upload_to="%Y/%m/%d/", blank=True, null=True)
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')

    class Meta:
        ordering = ['-updated', '-created']
        verbose_name = 'Дополнение к переводу'
        verbose_name_plural = 'Дополнения к переводу'

    def __str__(self):
        return self.note

    def get_update_url(self):

        """ Возвращаем url для обновления """

        print('добавляется')
        return reverse('content:updating_additional_object',
                       kwargs={'type_of_main_object': type(self.content_object).__name__.lower(),
                               'main_object': self.content_object.slug,
                               'content_type': 'additionally',
                               'object': self.pk})


class Phrase(Content):

    """ Какие-то фразы добавленные пользователем """

    title = None
    description = None
    phrase = models.CharField(max_length=300, unique=True, verbose_name='Фраза')
    translation = models.CharField(max_length=300, unique=True, verbose_name='Перевод')
    additionally = GenericRelation(Additionaly)

    class Meta:
        verbose_name = 'Фраза'
        verbose_name_plural = 'Фразы'

    def get_absolute_url(self):
        return reverse('content:showing_object_detail', kwargs={'content_type': 'phrase', 'object': self.slug})

    def get_update_url(self):
        return reverse('content:updating_object', kwargs={'content_type': 'phrase', 'object': self.slug})

    def get_additionally_url(self):

        """ Возвращаем url на указание дополнительной информации """

        return reverse('content:adding_additionall_object',
                       kwargs={'content_type': self.get_content_type(), 'object': self.slug})

    def get_delete_url(self):

        """ Получаем url для удаления фразы """

        return reverse('content:deleting_object',
                       kwargs={'main_object': 'phrase',
                               'content_type': self.group.slug,
                               'object': self.slug})

    def __str__(self):
        return self.phrase


class PartOfSpeech(models.Model):

    """ Часть речи """

    name = models.CharField(max_length=50, unique=True, verbose_name='Часть речи')
    slug = models.SlugField(verbose_name='URL')

    class Meta:
        verbose_name = 'Часть речи'
        verbose_name_plural = 'Части речи'


    def get_absolute_url(self):

        return reverse('content:showing_part_of_speech', kwargs={'part_of_speech': self.slug})


    def get_related_words(self):

        """ Получаем связанные слова """

        related_words = self.words.order_by('-updated')
        return related_words


    def __str__(self):
        return self.name


class Word(Content):

    """ Какие-то слова добавленные пользователем """

    title = None
    description = None
    group = None
    word = models.CharField(max_length=100, unique=True, verbose_name='Слово')
    translate = models.CharField(max_length=100, verbose_name='Перевод')
    part_of_speech = models.ForeignKey(PartOfSpeech, on_delete=models.CASCADE,
                                       related_name='words', verbose_name='Часть речи')
    photo = models.ImageField(upload_to="%Y/%m/%d/", blank=True, null=True)
    additionally = GenericRelation(Additionaly)

    class Meta:
        verbose_name = 'Слово'
        verbose_name_plural = 'Слова'

    def __str__(self):
        return self.word

    def get_absolute_url(self):
        return reverse('content:showing_object_detail',
                       kwargs={'content_type': self.part_of_speech.slug, 'object': self.slug})


    def get_update_url(self):

        """ Получаем url для обновления объекта """

        return reverse('content:updating_object',
                       kwargs={'content_type': self.part_of_speech.slug, 'object': self.slug})

    def get_additionally_url(self):

        """ Возвращаем url на указание дополнительной информации """

        return reverse('content:adding_additionall_object',
                       kwargs={'content_type': 'word', 'object': self.slug})

    def get_update_additional_url(self):

        """ Получаем url указывающий на обновление дополнительной информации """

        return reverse('content:updating_object',
                       kwargs={'content_type': self.part_of_speech.slug, 'object': self.slug})

    def get_add_url(self):

        """ Получаем url для добавления объекта """

        return reverse('content:showing_object_category',
                       kwargs={'content_type': 'word', 'object': self.part_of_speech.slug}) 

    def get_delete_url(self):

        """ Получаем url для удаления объекта """

        return reverse('content:deleting_object',
                       kwargs={'main_object': 'word',
                               'content_type': self.part_of_speech.slug,
                               'object': self.slug})


class Verb(Word):

    """ Часть речи - глагол """

    simple_past = models.CharField(max_length=100)
    past_participle = models.CharField(max_length=100)

    class Meta:
        verbose_name = 'Глагол'
        verbose_name_plural = 'Глаголы'


    def get_add_url(self):

        """ Получаем url для добавления объекта """

        return reverse('content:showing_object_category',
                kwargs={'content_type': 'word', 'object': 'glagoly'}) 


    def get_update_url(self):

        """ Получаем url для обновления объекта """

        return reverse('content:updating_object',
                       kwargs={'content_type': 'glagoly', 'object': self.slug})


    def get_delete_url(self):

        """ Получаем url для удаления объекта """

        return reverse('content:deleting_object',
                       kwargs={'main_object': 'word',
                               'content_type': 'glagoly',
                               'object': self.slug})


